- 是一个计算机科学的概念
- 用于使用单个字符串来描述,匹配一系列匹配某个句法规则的字符串
- 常用来检索,替换某些模式的文本
# 正则表达是的写法
- .(点号): 匹配任意一个字符,出了 \n
- []:匹配中括号中列举的字符,例如[LY]
- \d: 表示任意一个数字, 0-9
- \D: 表示非数字,即不是数字就可以
- \s:匹配空白,即空格,tab键
- \S:除了空白意外的字符
- \w:单词字符,即a-z, A-Z, 0-9, _
- \W:非单词字符
- *: 表示前面内容重复零次或者多次
- +:前面内容重复至少一次
- ?:前面出现的内容零次或者一次
- {m,n}:允许前面内容出现最少m次,最多n次
- ^:匹配字符串的开始
- $:匹配字符串的结尾
- \b:匹配单词的边界
- ():对正则表达式内容进行分组, 从第一个括号开始,编号逐渐增大
验证一个数字: ^\d$
必须有一个数字,最少一位:^\d+$
只能出现数字,且位数为5-10位: ^\d{5,10}$
注册者输入年龄,要求16岁以上,99岁以下: ^[16-99]$
只能输入英文字符和数字: ^[A-Za-z0-9]$
验证qq号码: [0-9]{5,12}
- \A: 只匹配字符串开头, \Aabcd, 则abcd
- \Z: 仅匹配字符串末尾, abcd\Z, abcd
- |: 左右任意一个
- (?P<name>...): 分组,除了原来的编号再制定一个别名, (?P<id>12345){2}, 1234512345
- (?P=name): 引用分组,
# re 模块
- re.match(re_exp):从开始查看是否能跟定义的正则相匹配
- result.group:如果匹配数据成功,可以使用group来提取数据
- 案例01
# re中原生字符串问题
- 字符串中会包含转义字符
- 在re中,转义字符会带来一些麻烦,能不能尽量减少转义字符的出现
- 在字符串前使用r字符,表示后面字符串是原始字符串,不需要转移,例如 r'c:\wk\readme.txt'
- 案例01-fun_4
# 正则的分组表示
- |:匹配左右任意一个表达式
- (ab):将括号中字符作为一个分组
- \num:引用分组num匹配到的字符串
- (?P<name>):分组起一个别名, 其中P是大写
- (?P=num):引用别名为name分组匹配到的字符串
- 案例01中 fun_5函数
# re 模块的一般使用步骤如下:
1. 使用 compile() 函数将正则表达式的字符串形式编译为一个 Pattern 对象
2. 通过 Pattern 对象提供的一系列方法对文本进行匹配查找,获得匹配结果,一个 Match 对象。
3. 最后使用 Match 对象提供的属性和方法获得信息,根据需要进行其他的操作
# re常用函数
- group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可 直接使用 group() 或 group(0);
- start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索 引),参数默认值为 0;
- end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引 +1),参数默认值为 0;
- span([group]) 方法返回 (start(group), end(group))。
# 正则的其他用法
- 案例01, fun_6
- search:查找其中一个内容
- findall:查找所有内容
- sub:查找替换, 返回替换之后的内容,原来倍替换的内容不变
# 匹配代码
import re
p = re.compile(r'\d+')
m = p.match("one12twothree34four")
print(m)
import re
m = p.match("one12twothree34four", 3, 10)
print(m)
print(m[0])
m.start(0) # 参数是组号
m.end(0)
#第二个例子
import re
p = re.compile(r'([a-z]+) ([a-z]+)',re.I) # re.I表示忽略大小写, 两个中间有空格
m = p.match('I really love wangxiaojing ')
print(m)
print(m.group(0))
m.start(0)
m.span(0)
m.group(1)
m.group(2)
m.group(0) # 整个匹配子串
m.groups() # 全部的打印出来
# 查找代码
- search(str[, pos[, endpos]])
- findall
- finditer
import re
p = re.compile(r'\d+')
m = p.search('one12twothree34four')
m.group()
p = re.compile('\d+')
m = p.search('hello 123456 7890')
print(m.group())
#findall
rst = p.findall("hello 12345 67890")
print(rst)
# sub替换
- sub(rep1, str[,count])
import re
p = re.compile(r'(\w+) (\w+)') #\w是字符
s = "hello 123 and hello 456"
rst = p.sub(r'hello world', s)
print(rst)
rst = p.sub(r'\2 \1', s)
print(rst)
def func(m):
return 'gaga' + m.group(2)
rst = p.sub(func, s)
print(rst)
rst = p.sub(func, s,1)
print(rst)
# 匹配中文
- 中文主要表示范围是 [u4e00-u9fa5], 不包括拳脚标点
import re
title = u'你好 世界, hello moto'
p = re.compile(ur"[\u4e00-\u9fa5]+") # ur有可能冲突
rst = p.findall(title)
print(rst)
# 贪婪和非贪婪
- 尽可能多的匹配,(*)
- 非贪婪, (?)
- 默认贪婪
import re
title = u'<div>name</div><div>age</div>'
p1 = re.compile(r"<div>.*</div>")
p2 = re.compile(r"<div>.*?</div>")
m1 = p1.search(title)
print(m1.group())
m2 = p2.search(title)
print(m2.group())